package com.huaxin.common.media.vidio;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.huaxin.common.BaseActivity;
import com.huaxin.common.Global;
import com.huaxin.common.R;
import com.huaxin.common.utils.Util;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class CustomRecordActivity extends BaseActivity implements View.OnClickListener {

    private static final String TAG               = "CustomRecordActivity";
    public static final  int    CONTROL_CODE      = 1;
    private static final int    CALL_BACK         = 0;
    private static final int    MAX_RECORDER_TIME = 10 * 1000;
    //UI
    private ImageView     mRecordControl;
    private ImageView     mPauseRecord;
    private SurfaceView   surfaceView;
    private SurfaceHolder mSurfaceHolder;
    private Chronometer   mRecordTime;

    //DATA
    private boolean isRecording;// 标记，判断当前是否正在录制
    private boolean isPause; //暂停标识
    private long mPauseTime = 0;           //录制暂停时间间隔

    // 存储文件
    private File          mVecordFile;
    private Camera        mCamera;
    private MediaRecorder mediaRecorder;
    private String        currentVideoFilePath;
    private String saveVideoPath = "";
    private static VideoCallBack callback;

    private Handler mHandler = new MyHandler(this);
    private ProgressBar pb_recorder;

    @Override
    protected int getContentViewId() {
        return R.layout.activity_custom;
    }

    @Override
    public void initView() {
        super.initView();
        surfaceView = (SurfaceView) findViewById(R.id.record_surfaceView);
        mRecordControl = (ImageView) findViewById(R.id.record_control);
        mRecordTime = (Chronometer) findViewById(R.id.record_time);
        mPauseRecord = (ImageView) findViewById(R.id.record_pause);
        pb_recorder = (ProgressBar) findViewById(R.id.pb_recorder);
        pb_recorder.setMax(MAX_RECORDER_TIME);
        pb_recorder.setProgress(0);

        mRecordControl.setOnClickListener(this);
        mPauseRecord.setOnClickListener(this);
        mPauseRecord.setEnabled(false);

        //配置SurfaceHodler
        mSurfaceHolder = surfaceView.getHolder();
        // 设置Surface不需要维护自己的缓冲区，可减轻卡顿情况
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        // 设置分辨率
        //  mSurfaceHolder.setFixedSize(320, 280);
        // 设置该组件不会让屏幕自动关闭
        mSurfaceHolder.setKeepScreenOn(true);
        mSurfaceHolder.addCallback(mCallBack);//回调接口

        mRecordTime.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
            @Override
            public void onChronometerTick(Chronometer chronometer) {
                //SystemClock.elapsedRealtime()系统当前时间
                //chronometer.getBase()记录计时器开始时的时间
                Log.i("lwjing", "time:" + (SystemClock.elapsedRealtime() - chronometer.getBase()));
                pb_recorder.setProgress((int) (SystemClock.elapsedRealtime() - chronometer.getBase()));
                if ((SystemClock.elapsedRealtime() - chronometer.getBase()) > MAX_RECORDER_TIME) {
                    // mRecordTime.setBase(SystemClock.elapsedRealtime());
                    endRecorder();
                }
            }
        });
    }

    public static void addRecordVideoCallback(VideoCallBack callBack) {
        callback = callBack;
    }

    @Override
    protected void onDestroy() {
        callback = null;
        super.onDestroy();
    }

    public interface VideoCallBack {
        void recordVideoDone(String path);
    }

    private static class MyHandler extends Handler {
        private final WeakReference<CustomRecordActivity> mActivity;

        public MyHandler(CustomRecordActivity activity) {
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            System.out.println(msg);
            if (mActivity.get() == null) {
                return;
            }
            switch (msg.what) {
                case CONTROL_CODE:
                    //开启按钮
                    mActivity.get().mRecordControl.setEnabled(true);
                    break;
                case CALL_BACK:
                    String videoPath = (String) msg.obj;
                    if (callback != null)
                        callback.recordVideoDone(videoPath);
                    break;
            }
        }
    }


    private MediaRecorder.OnErrorListener OnErrorListener = new MediaRecorder.OnErrorListener() {
        @Override
        public void onError(MediaRecorder mediaRecorder, int what, int extra) {
            try {
                if (mediaRecorder != null) {
                    mediaRecorder.reset();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };


    private SurfaceHolder.Callback mCallBack = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {
            initCamera();
        }

        @Override
        public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
            if (mSurfaceHolder.getSurface() == null) {
                return;
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
            stopCamera();
        }
    };


    /**
     * 初始化摄像头
     *
     * @throws IOException
     * @author liuzhongjun
     * @date 2016-3-16
     */
    private void initCamera() {
        if (mCamera != null) {
            stopCamera();
        }
        //默认启动后置摄像头
        mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
        if (mCamera == null) {
            Toast.makeText(this, "未能获取到相机！", Toast.LENGTH_SHORT).show();
            return;
        }
        try {
            //消除声音
            mCamera.enableShutterSound(false);
            mCamera.setPreviewDisplay(mSurfaceHolder);
            //配置CameraParams
            setCameraParams();
            //启动相机预览
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }


    private void setCameraParams() {

        if (mCamera != null) {
            Camera.Parameters params = mCamera.getParameters();
            //设置相机的横竖屏(竖屏需要旋转90°)
            if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
                params.set("orientation", "portrait");
                mCamera.setDisplayOrientation(90);
            } else {
                params.set("orientation", "landscape");
                mCamera.setDisplayOrientation(0);
            }
            //设置聚焦模式
            List<String> focusModeList = params.getSupportedFocusModes();
            if (focusModeList != null && focusModeList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
                //连续对焦模式，但不是所有手机都支持,运动拍摄情况下，部分机型会出现马赛克的情况
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            } else {
                params.setFocusMode(Camera.Parameters.FLASH_MODE_AUTO);
            }
            //缩短Recording启动时间
            params.setRecordingHint(true);
            //开启HRD
            if (params.getSupportedSceneModes().contains(Camera.Parameters.SCENE_MODE_HDR))
                params.setSceneMode(Camera.Parameters.SCENE_MODE_HDR);
            //影像稳定能力，防抖
            if (params.isVideoStabilizationSupported())
                params.setVideoStabilization(true);
            mCamera.setParameters(params);
        }
    }


    /**
     * 释放摄像头资源
     */
    private void stopCamera() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * 开始录制视频
     */
    public void startRecord() {
        initCamera();
        mCamera.unlock();
        setConfigRecord();
        try {
            //开始录制
            mediaRecorder.prepare();
            mediaRecorder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
        isRecording = true;
        if (mPauseTime != 0) {
            mRecordTime.setBase(SystemClock.elapsedRealtime() - (mPauseTime - mRecordTime.getBase()));
        } else {
            mRecordTime.setBase(SystemClock.elapsedRealtime());
        }
        mRecordTime.start();
    }

    /**
     * 将String类型的时间转换成long,如：12:01:08
     *
     * @param strTime String类型的时间
     * @return long类型的时间
     */
    protected long convertStrTimeToLong(String strTime) {
        String[] timeArry = strTime.split(":");
        long longTime = 0;
        if (timeArry.length == 2) {//如果时间是MM:SS格式
            longTime = Integer.parseInt(timeArry[0]) * 1000 * 60 + Integer.parseInt(timeArry[1]) * 1000;
        } else if (timeArry.length == 3) {//如果时间是HH:MM:SS格式
            longTime = Integer.parseInt(timeArry[0]) * 1000 * 60 * 60 + Integer.parseInt(timeArry[1])
                    * 1000 * 60 + Integer.parseInt(timeArry[0]) * 1000;
        }
        return SystemClock.elapsedRealtime() - longTime;
    }

    /**
     * 结束录制视频
     */
    public void stopRecord() {
        if (isRecording && mediaRecorder != null) {
            Log.i("lwjing", "stop recorder video");
            // 设置后不会崩
            mediaRecorder.setOnErrorListener(null);
            mediaRecorder.setPreviewDisplay(null);
            //停止录制
            mediaRecorder.stop();
            mediaRecorder.reset();
            //释放资源
            mediaRecorder.release();
            mediaRecorder = null;
            //Chronometer stop后，只是时间停止刷新，但记时并没有停止
            mRecordTime.stop();
/*            //设置开始按钮可点击，停止按钮不可点击
            mRecordControl.setEnabled(true);
            mPauseRecord.setEnabled(false);*/
            isRecording = false;
            mCamera.lock();
        } else {
            mRecordTime.stop();
            isRecording = false;
        }
    }

    public void contiuneRecord() {
        mRecordTime.setBase(convertStrTimeToLong(mRecordTime.getText().toString()));
        mRecordTime.start();
        initCamera();
        mCamera.unlock();
        setConfigRecord();
        try {
            //开始录制
            mediaRecorder.prepare();
            mediaRecorder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
        isRecording = true;
    }


    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.record_control) {
            Log.i("lwjing", "isPause:" + isPause + "isRecording:" + isRecording);
            if (isPause) {
                //代表视频暂停录制后点击中心，继续录制视频
                Log.i("lwjing", "time isPause:" + mRecordTime.getText());
                //继续录制
                mPauseRecord.setImageResource(R.drawable.control_pause);
                //继续视频录制
                contiuneRecord();
                isPause = false;

            } else {
                if (!isRecording) {
                    //开始录制视频
                    startRecord();
                    mRecordControl.setImageResource(R.drawable.recordvideo_stop);
                    mRecordControl.setEnabled(false);//1s后才能停止
                    mHandler.sendEmptyMessageDelayed(CONTROL_CODE, 1000);
                    mPauseRecord.setVisibility(View.VISIBLE);
                    mPauseRecord.setEnabled(true);
                } else {
                    //结束视频录制
                    mRecordControl.setImageResource(R.drawable.recordvideo_start);
                    mPauseRecord.setVisibility(View.GONE);
                    mPauseRecord.setEnabled(false);
                    stopRecord();
                    stopCamera();
                    mPauseTime = 0;
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                if (!(saveVideoPath.equals(""))) {
                                    String[] str = new String[]{saveVideoPath, currentVideoFilePath};
                                    VideoUtils.appendVideo(CustomRecordActivity.this, getSDPath(CustomRecordActivity.this) + "append.mp4", str);
                                    File reName = new File(saveVideoPath);
                                    File f = new File(getSDPath(CustomRecordActivity.this) + "append.mp4");
                                    f.renameTo(reName);//将合成的视频复制过来
                                    if (reName.exists()) {
                                        f.delete();
                                        new File(currentVideoFilePath).delete();
                                    }
                                }
                                String videoPath;
                                if (saveVideoPath.equals("")) {
                                    videoPath = currentVideoFilePath;
                                } else {
                                    videoPath = saveVideoPath;
                                }
                                Log.i("lwjing", "time:" + mRecordTime.getText() + " isRecording:" + isRecording);
                                callback(videoPath);
                                // setResult(videoPath);

                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }).start();
                }
            }

            return;
        }

        if (view.getId() == R.id.record_pause) {

            if (isRecording) { //正在录制的视频，点击后暂停
                mPauseRecord.setImageResource(R.drawable.control_play);
                //暂停视频录制
                mCamera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        if (success == true)
                            CustomRecordActivity.this.mCamera.cancelAutoFocus();
                    }
                });
                //停止录制
                stopRecord();
                stopCamera();
                isPause = true;

                if (saveVideoPath.equals("")) {
                    saveVideoPath = currentVideoFilePath;
                } else {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                String[] str = new String[]{saveVideoPath, currentVideoFilePath};
                                VideoUtils.appendVideo(CustomRecordActivity.this, getSDPath(getApplicationContext()) + "append.mp4", str);
                                File reName = new File(saveVideoPath);
                                File f = new File(getSDPath(getApplicationContext()) + "append.mp4");
                                f.renameTo(reName);
                                if (reName.exists()) {
                                    f.delete();
                                    new File(currentVideoFilePath).delete();
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }).start();
                }

            } else {
                mPauseRecord.setImageResource(R.drawable.control_pause);
                //继续视频录制
                contiuneRecord();
                isPause = false;
            }
            return;
        }
    }

    public static String getSDPath(Context context) {
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
        if (sdCardExist) {
            sdDir = Environment.getExternalStorageDirectory();
        } else if (!sdCardExist) {

            Toast.makeText(context, "SD卡不存在", Toast.LENGTH_SHORT).show();

        }
        File eis = new File(sdDir.toString() + "/HxVideo/");
        try {
            if (!eis.exists()) {
                eis.mkdir();
            }
        } catch (Exception e) {

        }
        return sdDir.toString() + "/HxVideo/";
    }


    /**
     * 配置MediaRecorder()
     */
    private void setConfigRecord() {
        mediaRecorder = new MediaRecorder();
        mediaRecorder.reset();
        mediaRecorder.setCamera(mCamera);
        mediaRecorder.setOnErrorListener(OnErrorListener);

        //使用SurfaceView预览
        mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
        //1.设置采集声音
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        //设置采集图像
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        //2.设置视频，音频的输出格式 mp4
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
        //3.设置音频的编码格式
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        //设置图像的编码格式
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        // 设置视频质量
        //        CamcorderProfile profile = CamcorderProfile
        //                .get(CamcorderProfile.QUALITY_HIGH);
        // 设置分辨率 小米4c这样设置会导致内存泄漏
        //        mediaRecorder.setVideoSize(profile.videoFrameWidth,
        //                profile.videoFrameHeight);
        mediaRecorder.setVideoSize(640, 480);
        // 设置高质量录制，改变码率 和大小有关
        mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
        //        mediaRecorder.setProfile(profile);
        // 设置帧率  流畅度
        mediaRecorder.setVideoFrameRate(30);
        //设置最大录像时间 单位：毫秒
        mediaRecorder.setMaxDuration(MAX_RECORDER_TIME);

        //设置选择角度，顺时针方向，因为默认是逆向90度的，这样图像就是正常显示了,这里设置的是观看保存后的视频的角度
        mediaRecorder.setOrientationHint(90);

        //设置录像视频保存地址
        currentVideoFilePath = getSDPath(getApplicationContext()) + getVideoName();
        mediaRecorder.setOutputFile(currentVideoFilePath);
        //最大文件size 回调
        mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
            public void onInfo(MediaRecorder mr, int what, int extra) {
            }
        });
    }

    private String getVideoName() {
        return Global.getUser().getUserId() + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".mp4";
    }

    @Override
    public void onBackPressed() {
        //  super.onBackPressed();
        Log.i("lwjing", "backPressed");
        //返回键监听 停止录制
        endRecorder();
    }

    private void endRecorder() {
        stopRecord();
        stopCamera();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    if (!(saveVideoPath.equals(""))) {
                        String[] str = new String[]{saveVideoPath, currentVideoFilePath};
                        VideoUtils.appendVideo(CustomRecordActivity.this, getSDPath(CustomRecordActivity.this) + "append.mp4", str);
                        File reName = new File(saveVideoPath);
                        File f = new File(getSDPath(CustomRecordActivity.this) + "append.mp4");
                        f.renameTo(reName);//将合成的视频复制过来
                        if (reName.exists()) {
                            f.delete();
                            new File(currentVideoFilePath).delete();
                        }
                    }
                    String videoPath;
                    if (saveVideoPath.equals("")) {
                        videoPath = currentVideoFilePath;
                    } else {
                        videoPath = saveVideoPath;
                    }
                    // setResult(videoPath);
                    callback(videoPath);

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void callback(String videoPath) {
        //子线程
        if (!Util.checkNull(videoPath)) {
            Message message = new Message();
            message.what = CALL_BACK;
            message.obj = videoPath;
            mHandler.sendMessage(message);
        }
        finish();
    }

    private void setResult(String videoPath) {
        Log.i("lwjing", "setResult videoPath=" + videoPath);
        Intent intent = getIntent();
        intent.putExtra("videoPath", videoPath);
        setResult(10, intent);
        finish();
    }
}
